#coding=utf-8

import functools
import traceback
from flask import request
from flask import redirect
from flask import url_for
from dbs.models import *
from common.render import Render
from common.utils import *
from conf.constant import *
from common.write_log import writelog
from common.write_object import write_object

# 登录校验
# 用户类型user_type(预留)
def authenticated(user_type=None):

    def decorator(method):
        @functools.wraps(method)
        def wrapper(view):
            try:
                token = view.params.get('token', '')
                if not token:
                    return view._render.render_json(code=RESPONSE_NEED_LOGIN, data={}, msg='请先登陆!')

                user_item = db.session.query(User).filter(User.token == token, User.is_deleted == False).first()
                # 找不到用户
                if not user_item:
                    return view._render.render_json(code=RESPONSE_NEED_LOGIN, data={}, msg='请先登陆!')

                # 把用户对象放到view对象中
                view.user = user_item
            except:
                writelog(traceback.format_exc())

            return method(view)
        return wrapper
    return decorator


# 校验参数(可以校验string，number，int, bool, dict)
def verify_params(**kwargs):
    def decorator(method):
        @functools.wraps(method)
        def wrapper(view):
            try:
                for key in kwargs:
                    value = view.params.get(key)
                    print(type(value))

                    if value is None:
                        return view._render.render_json(code=RESPONSE_PARAMS_ERROR, data={}, msg='%s不能为空!' % str(key))

                    # 字符串形式(默认接到的都是字符串)
                    if kwargs[key] == 'string':
                        if not isinstance(value, str) and not isinstance(value, unicode):
                            return view._render.render_json(code=RESPONSE_PARAMS_ERROR, data={}, msg='%s必须是字符串!' % str(key))
                    # 数值型（整数，浮点数）
                    if kwargs[key] == 'number':
                        if not is_digit(value):
                            return view._render.render_json(code=RESPONSE_PARAMS_ERROR, data={}, msg='%s必须是数字!' % str(key))
                    # 整数
                    if kwargs[key] == 'int':
                        if not is_int(value):
                            return view._render.render_json(code=RESPONSE_PARAMS_ERROR, data={}, msg='%s必须是整型!' % str(key))
                    # 布尔
                    if kwargs[key] == 'bool':
                        if not isinstance(value, bool):
                            return view._render.render_json(code=RESPONSE_PARAMS_ERROR, data={}, msg='%s必须是布尔!' % str(key))
                    # 列表
                    if kwargs[key] == 'list':
                        if not isinstance(value, list):
                            return view._render.render_json(code=RESPONSE_PARAMS_ERROR, data={}, msg='%s必须是列表!' % str(key))
                    # 字典
                    if kwargs[key] == 'dict':
                        if not isinstance(value, dict):
                            return view._render.render_json(code=RESPONSE_PARAMS_ERROR, data={}, msg='%s必须是字典!' % str(key))
            except:
                writelog(traceback.format_exc())

            return method(view)
        return wrapper
    return decorator


# 改写flask的路由，默认支持OPTIONS
def dispatch(rule, **options):

    def decorator(method):
        options['methods'] = options['methods'] or []
        if 'OPTIONS' not in options['methods']:
            options['methods'].append('OPTIONS')

        if not hasattr(method, '_rule_cache') or method._rule_cache is None:
            method._rule_cache = {method.__name__: [(rule, options)]}
        elif not method.__name__ in method._rule_cache:
            method._rule_cache[method.__name__] = [(rule, options)]
        else:
            method._rule_cache[method.__name__].append((rule, options))

        @functools.wraps(method)
        def wrapper(view):
            if request.method == 'OPTIONS':
                return view._render.render_json(code=RESPONSE_SUCCESS, data={}, msg='success')
            return method(view)
        return wrapper

    return decorator